#ifndef JAM_INTERPRETER_H
#define JAM_INTERPRETER_H

#ifdef _MSC_VER
#pragma once
#endif

#include "jam_ast.hpp"
#include "exec_context.hpp"

class jam_interpeter
{
	jam_context_ptr context_;
public:
	jam_interpeter(jam_context_ptr context);

	void intepret_tree(const parse_node_base *node, jam_module_ptr module, jam_list *res);
	void intepret_tree(const parse_node_base *node, jam_module_ptr module, 
		jam_frame *cur_frame,jam_list *res);

	static bool is_null(const parse_node_base *node)
	{
		if (!node) return true;
		return node->get_node_id()==null_node::node_id;
	}

private:
	void dispatch_node(const parse_node_base *node, jam_frame *frame, jam_list *res);
	void parse_lol(const parse_node_base *node, jam_frame *frame, list_of_lists &res);

	int lcmp(const jam_list &t, const jam_list &s);
	bool evaluate_eval_real(const eval_node *rule, jam_frame *frame);
	void evaluate_set_real(const jam_list &names, const parse_node_base *val_tree, 
		assignment_operation operation, jam_frame *frame, jam_list *res);

	void evaluate_module(const module_node *mod, jam_frame *frame, jam_list *res);

	void evaluate_local(const local_node *rule, jam_frame *frame, jam_list *res);
	void evaluate_if(const if_node *rule, jam_frame *frame, jam_list *res);
	void evaluate_while(const while_node *rule, jam_frame *frame, jam_list *res);
	void evaluate_switch(const switch_node *rule, jam_frame *frame, jam_list *res);
	void evaluate_save_rule(const setcomp_node *rule, jam_frame *frame, jam_list *res);
	void evaluate_for(const foreach_node *rule, jam_frame *frame, jam_list *res);
	void evaluate_set(const set_node *rule, jam_frame *frame, jam_list *res);
	void evaluate_rule(const rule_node *rule, jam_frame *frame, jam_list *res);	
};

#endif //JAM_INTERPRETER_H
